package timing.ukulele.portal.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import timing.ukulele.persistent.service.BaseService;
import timing.ukulele.portal.mapper.UserMapper;
import timing.ukulele.portal.persistent.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import timing.ukulele.portal.persistent.System;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserService extends BaseService<UserMapper, User> {

    private final SystemService systemService;
    private final PasswordEncoder passwordEncoder;

    public UserService(SystemService systemService, PasswordEncoder passwordEncoder) {
        this.systemService = systemService;
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 获取分页
     *
     * @param map    查询名称
     * @param mySystem 系统权限
     * @param current 当前也页，从1开始
     * @param size    每页大小
     * @return 模板数据
     */
    public IPage<User> getPage(Map<String, Object> map, String mySystem, int current, int size) {
        Page<User> page = new Page<>(current, size);
        LambdaQueryWrapper<User> qw = new LambdaQueryWrapper<>();
        if (map.get("name") != null) {
            qw.like(User::getName, map.get("name"));
        }
        if (map.get("username") != null) {
            qw.like(User::getUsername, map.get("username"));
        }
        qw.orderByDesc(User::getId);
        List<Long> mySystemIds = null;
        if (!"".equals(mySystem)) {
            String[] split = mySystem.split(",");
            if (!"0".equals(split[0])) {
                mySystemIds = Arrays.asList(split).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                qw.in(User::getId, getBaseMapper().getUserIdsBySystemIds(mySystemIds));
            }
        }
        IPage<User> iPage = getBaseMapper().selectPage(page, qw);
        if (null != iPage && !CollectionUtils.isEmpty(iPage.getRecords())) {
            List<User> users = iPage.getRecords();
            for (User user : users) {
                user.setPassword(null);
                List<Long> systemIds = getBaseMapper().getSystemIdsByUserId(user.getId());
                List<Long> sameSystemIds = new ArrayList<>();
                if (mySystemIds != null && mySystemIds.size() > 0) {
                    for (Long myId : mySystemIds) {
                        for (Long id : systemIds) {
                            if (myId.equals(id)) {
                                sameSystemIds.add(myId);
                            }
                        }
                    }
                } else {
                    sameSystemIds = systemIds;
                }
                user.setSystemIds(sameSystemIds);
                StringBuilder systemName = new StringBuilder();
                for (Long systemId : sameSystemIds) {
                    System system = systemService.getById(systemId);
                    if ("".equals(systemName.toString())) {
                        systemName.append(system.getName());
                    } else {
                        systemName.append("，");
                        systemName.append(system.getName());
                    }
                    user.setSystemName(systemName.toString());
                }
            }
//            iPage.getRecords().forEach(item -> item.setPassword(null));
        }
        return iPage;
    }

    public Boolean saveUserSystem(Long userId, List<Long> systemIds, HashMap<String, Object> map) {
        List<Long> mySystemIds = (List<Long>) map.get("systemIds");
        if (mySystemIds != null && mySystemIds.size() > 0) {
            getBaseMapper().removeSystemIdsByRole(userId, mySystemIds);
        } else {
            getBaseMapper().removeSystemIdsByUserId(userId);
        }
        for (Long systemId : systemIds) {
            getBaseMapper().saveUserStytem(userId, systemId);
        }
        return true;
    }

    public User getByUsername(String username) {
        QueryWrapper<User> qw = new QueryWrapper<>(new User());
        qw.eq("username", username);
        User user = getBaseMapper().selectOne(qw);
        List<Long> systemIdsByUserId = getBaseMapper().getSystemIdsByUserId(user.getId());
        if (!CollectionUtils.isEmpty(systemIdsByUserId)) {
            user.setSystemIds(systemIdsByUserId);
        }
        return user;
    }

    public Boolean updatePassword(String oldPassword, String newPassword, Long updateUserId) {
        User user = getBaseMapper().selectById(updateUserId);
        if (user == null || !passwordEncoder.matches(oldPassword, user.getPassword())) {
            return false;
        }
        user.setPassword(newPassword);
        getBaseMapper().updateById(user);
        return true;
    }

    public List<System> getUserSystemList(String username) {
        User user = getByUsername(username);
        if (user == null)
            return null;
        List<Long> systemIdByUserId = systemService.getSystemIdByUserId(user.getId());
        if (CollectionUtils.isEmpty(systemIdByUserId))
            return null;
        List<System> list = systemService.lambdaQuery().in(System::getId, systemIdByUserId).list();
        return list;
    }

}
